/**
*
* myAJAX:  My AJAX implemetation
* Copyright (c) 2006, Raul IONESCU
*                     Bucharest, ROMANIA
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @package      myAJAX
* @copyright 	Copyright (c) 2006, Raul IONESCU.
* @author 	Raul IONESCU <ionescu.raul@gmail.com>
* @license      http://www.opensource.org/licenses/mit-license.php The MIT License
* @version 	2.12.0
* @category 	Javascript functions for AJAX
* @access 	public
*
*/
/////////////////////////////////////////////////////////////////////////
var constants                                           = new Object();
constants.errorMessages                                 = new Object();
constants.HTTP                                          = new Object();
constants.XML                                           = new Object();
/////////////////////////////////////////////////////////////////////////
constants.errorMessages.NoAJAX                          = new String("XMLHttp (AJAX) not supported");
constants.errorMessages.XMLNodeMustBeObject             = new String("node parameter must be an object.");
constants.errorMessages.XMLInvalidDocumentNoRootName    = new String("Invalid XML document: root node name not found.");
constants.errorMessages.XMLInvalidDocumentNoRootObject  = new String("Invalid XML document: root node object not found.");
constants.errorMessages.XMLNodeObjectNotFound           = new String("Node object not found.");
constants.errorMessages.XMLNodeAttributeNotFound        = new String("Node attribute not found.");
constants.errorMessages.XMLTagNameNotFound              = new String("Tag name not found.");
/////////////////////////////////////////////////////////////////////////
constants.HTTP.readyState = new Object();
constants.HTTP.readyState.Uninitialized                 = new Number(0);//The object has been created but the open() method hasn't been called.
constants.HTTP.readyState.Loading                       = new Number(1);//The open() method has been called but the request hasn't been sent.
constants.HTTP.readyState.Loaded                        = new Number(2);//The request has been sent.
constants.HTTP.readyState.Interactive                   = new Number(3);//A partial response has been received.
constants.HTTP.readyState.Complete                      = new Number(4);//All data has been received and the connection has been closed
/////////////////////////////////////////////////////////////////////////
constants.HTTP.serverStatus = new Object();
constants.HTTP.serverStatus.OK                          = new Number(200);
constants.HTTP.serverStatus.Created                     = new Number(201);
constants.HTTP.serverStatus.NoContent                   = new Number(204);
constants.HTTP.serverStatus.ResetContent                = new Number(205);
constants.HTTP.serverStatus.PartialContent              = new Number(206);
constants.HTTP.serverStatus.BadRequest                  = new Number(400);
constants.HTTP.serverStatus.Unauthorized                = new Number(401);
constants.HTTP.serverStatus.Forbidden                   = new Number(403);
constants.HTTP.serverStatus.NotFound                    = new Number(404);
constants.HTTP.serverStatus.MethodNotAllowed            = new Number(405);
constants.HTTP.serverStatus.NotAcceptable               = new Number(406);
constants.HTTP.serverStatus.ProxyAuthenticationRequired = new Number(407);
constants.HTTP.serverStatus.RequestTimeout              = new Number(408);
constants.HTTP.serverStatus.LengthRequired              = new Number(411);
constants.HTTP.serverStatus.RequestedEntityTooLarge     = new Number(413);
constants.HTTP.serverStatus.RequestedURLTooLong         = new Number(414);
constants.HTTP.serverStatus.UnsupportedMediaType        = new Number(415);
constants.HTTP.serverStatus.InternalServerError         = new Number(500);
constants.HTTP.serverStatus.NotImplemented              = new Number(501);
constants.HTTP.serverStatus.BadGateway                  = new Number(502);
constants.HTTP.serverStatus.ServiceUnavailable          = new Number(503);
constants.HTTP.serverStatus.GatewayTimeout              = new Number(504);
constants.HTTP.serverStatus.HTTPVersionNotSupported     = new Number(505);
///////////////////////////////////////////////////////////////////////// 
constants.XML.NodeType                                  = new Object();
constants.XML.NodeType.Element                          = new Number(1);
constants.XML.NodeType.Attribute                        = new Number(2);
constants.XML.NodeType.Text                             = new Number(3);
constants.XML.NodeType.CDataSection                     = new Number(4);
constants.XML.NodeType.EntityReference                  = new Number(5);
constants.XML.NodeType.Entity                           = new Number(6);
constants.XML.NodeType.ProcessingInstruction            = new Number(7);
constants.XML.NodeType.Comment                          = new Number(8);
constants.XML.NodeType.Document                         = new Number(9);
constants.XML.NodeType.DocumentType                     = new Number(10);
constants.XML.NodeType.DocumentFragment                 = new Number(11);
constants.XML.NodeType.Notation                         = new Number(12);
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
function myAJAX(/*url=null,urlParameters=null,method='GET',refreshInterval=0,onProgressFunction=null,onReadyFunction=null,onErrorFunction=null,InnerHtmlId=null*/)
/*
Object myAJAX
/////////////////////////////////////////////////////////////////////////

   PARAMETERS
-------------------------------------------------------------------------
url                     = page's URL
urlParameters           = page's parameters
method                  = 'HEAD', 'GET' or 'POST' with a defaul value of 'GET'
refreshInterval         = sets the execution of AJAX request periodically for values not zero; it is expressed in msec.
onProgressFunction      =
onReadyFunction         = function called when server's response is constants.HTTP.serverStatus.OK 
onErrorFunction         = function called when server's response is other than constants.HTTP.serverStatus.OK 
InnerHtmlId             = is the ID of an html element who will be populated with the text response
   
   PROPERTIES
-------------------------------------------------------------------------
 same as PARAMETRS   

   METHODS
-------------------------------------------------------------------------
urlEncode(urlParameters)        = encode URL parameters
sendRequest()                   = performs AJAX request
abortRequest()                  = aborts AJAX request
/////////////////////////////////////////////////////////////////////////
*/
{
if (!(this instanceof (myAJAX))) return new myAJAX((arguments[0]==undefined)?(null):(arguments[0]), (arguments[1]==undefined)?(null):(arguments[1]), (arguments[2]==undefined)?('GET'):(arguments[2]), (arguments[3]==undefined)?(0):((isNaN(arguments[3]))?(0):(parseInt(arguments[3]))), (arguments[4]==undefined)?(null):(arguments[4]), (arguments[5]==undefined)?(null):(arguments[5]), (arguments[6]==undefined)?(null):(arguments[6]));
var errorOccured=false;
var intervalID=0;
var ajaxObject=newAJAX();
this.url=(arguments[0]==undefined)?(null):(arguments[0]);
this.urlParameters=(arguments[1]==undefined)?(null):(arguments[1]);
this.method=(arguments[2]==undefined)?('GET'):(arguments[2]);
this.refreshInterval=(arguments[3]==undefined)?(0):((isNaN(arguments[3]))?(0):(parseInt(arguments[3])));
this.onProgressFunction=(arguments[4]==undefined)?(null):(arguments[4]);
this.onReadyFunction=(arguments[5]==undefined)?(null):(arguments[5]);
this.onErrorFunction=(arguments[6]==undefined)?(null):(arguments[6]);
this.InnerHtmlId=(arguments[7]==undefined)?(null):(arguments[7]);
/////////////////////////////////////////////////////////////////////////
this.urlEncode=urlEncode;
/////////////////////////////////////////////////////////////////////////
this.sendRequest=function()
{ 
try
        {
         refreshInterval=(this.refreshInterval==undefined)?(0):((isNaN(this.refreshInterval))?(0):(parseInt(this.refreshInterval)));
         ajax.ajaxObject=ajaxObject;
         ajax(this.url, this.urlParameters, this.method, this.onProgressFunction, this.onReadyFunction, this.onErrorFunction, this.InnerHtmlId);
         this.abortRequest();
         if(this.refreshInterval) intervalID=setInterval('ajax("'+this.url+'", "'+this.urlParameters+'", "'+this.method+'", '+this.onProgressFunction+', '+this.onReadyFunction+', '+this.onErrorFunction+', "'+this.InnerHtmlId+'");',refreshInterval);        
         errorOccured=false;
        }
catch(e)
        {
         if(errorOccured==false)
                {
                 errorOccured=true;
                 this.sendRequest();
                }
          else throw e;       
        }
}
/////////////////////////////////////////////////////////////////////////
this.abortRequest=function()
{
try { if(intervalID) clearInterval(intervalID); } catch(e) {}
}
/////////////////////////////////////////////////////////////////////////  
}
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
function myXML(xmlDoc)
/*
Object myXML
/////////////////////////////////////////////////////////////////////////

   PARAMETERS
-------------------------------------------------------------------------
xmlDoc               = XML object returned by responseXML
   
   PROPERTIES
-------------------------------------------------------------------------
 same as PARAMETRS   

   METHODS
-------------------------------------------------------------------------
rootNodeName                                                            = returns root node's name of the XML document
rootNodeObject                                                          = returns root node object of the XML document
nodeObject(nodeName, index=0 | nodeObj)                                 = returns node object of the XML document
nodeValue(nodeName,index=0 | nodeObj)                                   = returns node's value
nodeAttribute=function(nodeName, index, attribute | nodeObj, attribute) = returns node's attribute
nodesByTagName(tagName)                                                 = returns a list of nodes with specified tag name
/////////////////////////////////////////////////////////////////////////
*/
{
if (!(this instanceof (myXML))) return new myXML(xmlDoc);

this.xmlDoc=xmlDoc;
/////////////////////////////////////////////////////////////////////////
this.rootNodeName=function()
{
try {
     var rootName=this.xmlDoc.documentElement.nodeName;
     if(rootName) return rootName;
     else throw new Error(constants.errorMessages.XMLInvalidDocumentNoRootName);
    } 
catch(e)
    {
     throw new Error(constants.errorMessages.XMLInvalidDocumentNoRootName);
    } 
}
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
this.rootNodeObject=function()
{
try {
     var rootObject=this.xmlDoc.documentElement;
     if(typeof(rootObject)=="object") return rootObject;
     else throw new Error(constants.errorMessages.XMLInvalidDocumentNoRootObject);
    }
catch(e)
    {     
     throw new Error(constants.errorMessages.XMLInvalidDocumentNoRootObject);
    } 
}
/////////////////////////////////////////////////////////////////////////  
this.nodeObject=function (node/*, index=0 */)
{
try {
     var index=(arguments[1]==undefined)?(0):(isNaN(arguments[1])?(0):(parseInt(arguments[1])));
     var nodeObj=(typeof(node)=='string')?(this.xmlDoc.getElementsByTagName(node).item(index)):(node);
     if(typeof(nodeObj)=="object") return nodeObj;
     else throw new Error(constants.errorMessages.XMLNodeObjectNotFound);
    }
catch(e)
    {
     throw new Error(constants.errorMessages.XMLNodeObjectNotFound);
    }
}
/////////////////////////////////////////////////////////////////////////  
this.nodeAttribute=function(node/*, index=0, attribute*/)
{
switch(arguments.length)
        {
                case 3:
                        if(typeof(node)=='object') node=node.toString(); 
                        var index=isNaN(arguments[1])?(0):(parseInt(arguments[1]));         
                        var attribute=(typeof(arguments[2])=='object')?(arguments[2].toString()):(arguments[2]);        
                        var nodeObj= this.nodeObject(node,index);
                        break;
                
                default:
                        if(typeof(node)!='object') throw new Error(constants.errorMessages.XMLNodeMustBeObject);
                        var attribute=arguments[1];        
                        var nodeObj= this.nodeObject(node);
        }
var attributeValue=null;

try { attributeValue = nodeObj.attributes[attribute].value; }
catch(e) 
        {
         var attributes = nodeObj.attributes;
         var attributesLength=attributes.length;
         for(var i=0; i<attributesLength; i++)
                if(attributes[i].name==attribute)
                        {
                         attributeValue = attributes[i].value;
                         break;
                        }
         if(attributeValue==null) throw new Error(constants.errorMessages.XMLNodeAttributeNotFound);
        }
return attributeValue;
}
/////////////////////////////////////////////////////////////////////////  
this.nodeValue=function(node/*, index=0 */)
{
try { 
     var index    = (arguments[1]==undefined)?(0):(isNaN(arguments[1])?(0):(parseInt(arguments[1])));
     var nodeObj  = this.nodeObject(node,index);
     return nodeObj.firstChild.nodeValue;
    } 
catch(e)
    {
     throw e;
    }
}
/////////////////////////////////////////////////////////////////////////  
this.nodesByTagName=function(tagName)
{
try {
      return this.xmlDoc.getElementsByTagName(tagName);
     }
catch(e)
     {
      throw new Error(constants.errorMessages.XMLTagNameNotFound);
     }     
}
/////////////////////////////////////////////////////////////////////////  
}
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
function urlEncode(urlParameters)
{

if(urlParameters)
        {
         if(typeof(urlParameters)=='object') urlParameters=urlParameters.toString();
         var encodedURL = new String(unescape(urlParameters)).split('&');

         for(var i=0;i<encodedURL.length;i++) 
                {
                 encodedURL[i]=encodedURL[i].split('=');
                 for(j=0;j<encodedURL[i].length;j++) encodedURL[i][j]=escape(encodedURL[i][j]);
                 encodedURL[i]=encodedURL[i].join("=");
                }
         encodedURL=encodedURL.join("&");
         return encodedURL;      
        }
return null;         
}
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
function newAJAX()
{
var ajaxObject = false;
if(typeof(XMLHttpRequest) != "undefined") ajaxObject = new XMLHttpRequest();
else {
      if(window.ActiveXObject) 
        {
         var avers = ["Microsoft.XmlHttp", "MSXML2.XmlHttp","MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.6.0"];
         for (var i = avers.length -1; i >= 0; i--) 
                {
                 try {
                       ajaxObject = new ActiveXObject(avers[i]);
                       break;
                      } 
                 catch(e) {}
                }
        }
      else throw new Error(constants.errorMessages.NoAJAX);
     }
return ajaxObject;     
}
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
function ajax(url/*,urlParameters=null,method='GET',onProgressFunction=null,onReadyFunction=null,onErrorFunction=null,InnerHtmlId=null,ajaxObject=null*/)
{
var random = "myAJAX=" + new Date().getTime() + new String(Math.random()).substr(2);
var myUrlEncodedParameters = urlEncode((arguments[1]==undefined)?(null):(arguments[1]));
var myMethod= new String((arguments[2]==undefined)?('GET'):(arguments[2])).toUpperCase();
var myOnProgressFunction=(arguments[3]==undefined)?(null):(arguments[3]);
var myOnReadyFunction=(arguments[4]==undefined)?(null):(arguments[4]);
var myOnErrorFunction=(arguments[5]==undefined)?(null):(arguments[5]);
var myInnerHtmlId=(arguments[6]==undefined)?(null):((typeof(arguments[6])=='object')?(arguments[6].toString()):(arguments[6]));
var ajaxObject=(arguments[7]==undefined)?((ajax.ajaxObject==undefined)?(newAJAX()):(ajax.ajaxObject)):(arguments[7]);


try {
     switch(myMethod)
                {
                        case "GET":     if(myUrlEncodedParameters==null) { ajaxObject.open(myMethod, url + "?" + random , true); }
                                         else { ajaxObject.open(myMethod, url + "?" + myUrlEncodedParameters + "&" + random , true); } 
                                         break;
                                         
                        case "POST":
                        case "HEAD":    
                                        ajaxObject.open(myMethod, url + "?" + random,true);
                                        break;
                }
     ajaxObject.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 

     if((myOnProgressFunction!=null) || (myOnReadyFunction!=null) || (myOnErrorFunction!=null) || (myInnerHtmlId!=null)) 
        { 
         ajaxObject.onreadystatechange = function() 
                {
                 if((ajaxObject.readyState==constants.HTTP.readyState.Interactive) && (myOnProgressFunction!=null)) 
                        {
                         try { var myContentLength=ajaxObject.getResponseHeader("Content-Length"); }
                         catch (e) { myContentLength = 0; }
                         
                         try { var myMsg=new String(ajaxObject.responseText); }
                         catch (e) { myMsg = ''; }
                         
                         myOnProgressFunction(myMsg,new Number(myContentLength));
                        } 

                 if (ajaxObject.readyState==constants.HTTP.readyState.Complete) 
                        { 
                         if(ajaxObject.status==constants.HTTP.serverStatus.OK) 
                                { 
                                 if((myInnerHtmlId!=null) && ajaxObject.responseText) 
                                        {
                                         var id=self.document.getElementById(myInnerHtmlId);
                                         var response=ajaxObject.responseText.split('<myAJAX>');
                                         
                                         if(id && ((id.innerHTML.length!=response[0].length) || (id.innerHTML!=response[0]))) 
                                                {
                                                 id.innerHTML = response[0];
                                                 if(response.length>1) eval(response[1]);
                                                }
                                         id=null;
                                        } 
                                 if(myOnReadyFunction!=null) 
                                        { 
                                         myOnReadyFunction((myMethod=="HEAD")?((new String(ajaxObject.getAllResponseHeaders())).split("\r\n")):(((ajaxObject.responseXML) || ((new String(ajaxObject.getResponseHeader("Content-type")).toUpperCase())=="TEXT/XML"))?(new myXML(ajaxObject.responseXML)):(new String(ajaxObject.responseText)))); 
                                        } 
                                }
                          else { if(myOnErrorFunction!=null)  { myOnErrorFunction(new String(ajaxObject.statusText),new Number(ajaxObject.status)); } }
                        } 
                }; 
        }
     else ajaxObject.onreadystatechange=null;
     
     switch(myMethod)
       {
                case "GET":     ajaxObject.send(null);
                                break;
                                         
                case "POST":
                case "HEAD":    ajaxObject.send(myUrlEncodedParameters);
                                break;
       }

     return ajaxObject;
    } 
catch(e) { throw e; }  
}
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
/////////////////////////////////////////////////////////////////////////  
